package com.wzw.basics.reflection.use;

import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 大多数常用于获取泛型中套取泛型的具体类型，如：Object<T> T 是一个泛型套泛型 <List<T>>
 * 如：FastJSON -> TypeReference<T>
 * Spring -> ParameterizedTypeReference<T>
 *
 * @author Wangzhiwen
 */
public abstract class TypeReference<T> {
    /**
     * 获取类型
     */
    private final Type type;

    private static final Map<String, Type> typeCaches = new ConcurrentHashMap<>(16);

    protected TypeReference() {
        // 子类调用
        Class<?> subClass = this.getClass();
        // 子类获取父类
        Type superclass = subClass.getGenericSuperclass();
        // 获取实际类型
        ParameterizedType parameterizedType = (ParameterizedType) superclass;
        Type[] arguments = parameterizedType.getActualTypeArguments();
        // 实际时Class
        Type argType = arguments[0];
        Type cachedType = typeCaches.get(argType.getTypeName());
        if (cachedType == null) {
            typeCaches.putIfAbsent(argType.getTypeName(), argType);
            cachedType = typeCaches.get(argType.getTypeName());
        }
        this.type = cachedType;
    }

    public static Type intern(ParameterizedTypeImpl type) {
        Type cachedType = typeCaches.get(type.getTypeName());
        if (cachedType == null) {
            typeCaches.putIfAbsent(type.getTypeName(), type);
            cachedType = typeCaches.get(type.getTypeName());
        }
        return cachedType;
    }

}
